package com.google.code.swingonfire.utility;

public abstract class Tokenizer
{

    public static class Token
    {
        private final Object value;
        private final int line;
        private final int column;

        public Token(Object value, int line, int column)
        {
            super();

            this.value = value;
            this.line = line;
            this.column = column;
        }

        public Object getValue()
        {
            return value;
        }

        public int getLine()
        {
            return line;
        }

        public int getColumn()
        {
            return column;
        }
    }

    private final Scanner scanner;

    public Tokenizer(String source)
    {
        this(source.toCharArray());
    }

    public Tokenizer(String source, int offset, int length)
    {
        this(source.toCharArray(), offset, length);
    }

    public Tokenizer(char[] source)
    {
        this(source, 0, source.length);
    }

    public Tokenizer(char[] source, int offset, int length)
    {
        super();

        scanner = new Scanner(source, offset, length);
    }

    public Token read()
    {
        int line = scanner.getLine();
        int column = scanner.getColumn();

        while (true)
        {
            char ch = scanner.getChar();

            if (ch == Scanner.END_OF_SOURCE)
            {
                return null;
            }

            return parse(scanner, line, column);
        }
    }

    protected abstract Token parse(Scanner scanner, int line, int column);

    /**
     * {@inheritDoc}
     */
    @Override
    public String toString()
    {
        return scanner.toString();
    }

}
